/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package nadesicoi

import org.hibernate.FetchMode as FM

import java.sql.*;
import java.util.*;
import groovy.sql.*;

/**
 *
 * @author SYSTEM
 */
@grails.persistence.Entity
class RAMCacheArticulos {
    int             id
    String          descripcion
    String          codigo
    String          unidad
    int             id_linea
    int             id_grupo
    int             id_articulo
    double          impuestos
    double          costo
    double          precioDescuento
    double          grupoDescuento
    double          utilidad
    double          precio
    double          existencias
    String          linea
    String          grupo
    int             version
    static mapping = {
        table   'RAMCacheArticulos'
    }
}

class CacheArticulos {
    static def IDAlmacen = Main.config.IDAlmacen[0].text() as int
    static def generar() {
        def renglon
        def tiempo = [bt:0,ct:0,dt:0,et:0,ft:0,gt:0,ht:0,jt:0]
        //RAMCacheArticulos.withTransaction {


        RAMCacheArticulos.executeUpdate('delete from nadesicoi.RAMCacheArticulos as rca')
        RAMCacheCodigos.executeUpdate('delete from nadesicoi.RAMCacheCodigos as rca')

        def ini = System.currentTimeMillis()
        def precio, precioFinal, existencias, codigos, ultimoID = -1
        //RAMCacheArticulos.withTransaction {
               
                    
        def db   = Sql.newInstance("jdbc:mysql://localhost/omoikane?user=root&password=&useOldAliasMetadataBehavior=true", "root", "", "com.mysql.jdbc.Driver")
        try {
          db.connection.autoCommit = false
          def query = """
              select art.id_articulo id, art.codigo codigo, art.descripcion descripcion, art.unidad unidad, art.id_linea IDLinea,
                     l.descuento lineaDescuento, g.descuento grupoDescuento, l.descripcion linea, g.descripcion grupo,
                     ex.cantidad cantidad, pre.costo costo, pre.descuento precioDescuento, pre.utilidad precioUtilidad,
                     art.impuestos impuestos, art.id_grupo IDGrupo
              from articulos art, precios pre, lineas l, grupos g, existencias ex
              where art.id_articulo = pre.id_articulo and
                    art.id_linea = l.id_linea and
                    art.id_grupo = g.id_grupo and
                    art.id_articulo = ex.id_articulo and
                    ex.id_almacen = ? and
                    pre.id_almacen = ex.id_almacen
            """
        //Articulos.findAll().every() {
        //
        //def c = Articulos.createCriteria()
        
        def clienteDescuento = Clientes.get(1).descuento //Por estándar 1 es público en general
        def hashCodigos = [:]

        //try {
        //db.eachRow("SELECT * FROM articulos") { row -> println "irow:${row}" }
        /*db.eachRow("SELECT id_articulo as id, codigo FROM codigos_articulos") { row ->
            if(hashCodigos[row.id] == null) { hashCodigos[row.id] = [] }
            hashCodigos[row.id] << row.codigo
        }*/
            
        //db.execute("INSERT INTO ramcachecodigos (id_articulo, codigo, nCodigo, version) VALUES (?,?,?,?)", [row.id, row.codigo, 1, 0])
        db.execute("insert into ramcachecodigos (id_articulo, codigo, version) select id_articulo, codigo, 0 from articulos")
        db.execute("insert into ramcachecodigos (id_articulo, codigo, version) select articulo_id, codigo, 0 from codigos_articulos")
        
        db.eachRow(query, [IDAlmacen]) { row ->
            tiempo.a    = System.currentTimeMillis()
            //results.currentRow.each { println "lala->"+it.dump() }
            //tiempo.b    = System.currentTimeMillis()
            //tiempo.bt  += tiempo.b - tiempo.a
            ultimoID    = row.id
            //tiempo.c    = System.currentTimeMillis()
            //tiempo.ct  += tiempo.c - tiempo.b
            tiempo.d    = System.currentTimeMillis()
            tiempo.dt  += tiempo.d - tiempo.a
            precioFinal = ArticulosFunciones.getPrecioConDatos([costo: row.costo, precioDescuento: row.precioDescuento,
                                                                lineaDescuento: row.lineaDescuento, utilidad: row.precioUtilidad,
                                                                clienteDescuento: clienteDescuento, impuestos: row.impuestos,
                                                                grupoDescuento: row.grupoDescuento])
            tiempo.e    = System.currentTimeMillis()
            tiempo.et  += tiempo.e - tiempo.d

            db.execute("INSERT INTO ramcachearticulos (codigo, costo, descripcion, id_linea, impuestos, "+
                       " linea, precio, precio_descuento, unidad, utilidad, existencias, grupo_descuento, id_grupo, grupo, "+
                       " id_articulo, version) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, 0)",
                        [row.codigo, row.costo, row.descripcion, row.IDLinea, row.impuestos, row.linea, precioFinal.total,
                        row.precioDescuento, row.unidad, row.precioUtilidad, row.cantidad, row.grupoDescuento, row.IDGrupo, row.grupo,
                        row.id])

            //tiempo.f    = System.currentTimeMillis()
            //tiempo.ft  += tiempo.f - tiempo.e
            
            tiempo.g    = System.currentTimeMillis()
            tiempo.gt  += tiempo.g - tiempo.e


            def n = 0
            /*
            hashCodigos[row.id].each {

                db.execute("INSERT INTO ramcachecodigos (id_articulo, codigo, version) VALUES (?,?,?)",
                            [row.id, it, 0])

                n++
            }
            */
            tiempo.j    = System.currentTimeMillis()
            tiempo.jt  += tiempo.j - tiempo.g

        }
        db.commit()
    } catch(Exception e) {
        db.rollback()
        Consola.error("Error al cargar caché de artículos en artículo: ${ultimoID}", e)
    } finally {
        db.close()
    }

    //}
    def tiempoTotal = System.currentTimeMillis() - ini
    return [tiempoTotal, tiempo]
    //}
    }
    static def actualizar(id) {
        RAMCacheArticulos.withTransaction {
                def row
                def c    = Articulos.createCriteria()
                def precio, precioFinal, existencias, codigos, renglon
                def clienteDescuento = Clientes.get(1).descuento //Por estándar 1 es público en general

                def filaMod = RAMCacheArticulos.findById_articulo(id)
                if(filaMod==null) { filaMod = new RAMCacheArticulos() }
                def results = c.list {
                          //maxResults(10)
                          eq("id", id as int)
                          fetchMode("linea", org.hibernate.FetchMode.EAGER)
                          fetchMode("grupo", org.hibernate.FetchMode.EAGER)
                          //fetchMode("codigos", org.hibernate.FetchMode.EAGER)
                    }
                 results.each {
                     precio      = Precios.get(new Precios(id_articulo:it.id, id_almacen:IDAlmacen))
                     existencias = Existencias.get(new Existencias(id_articulo:it.id, id_almacen:IDAlmacen))
                     precioFinal = ArticulosFunciones.getPrecioConDatos([costo: precio.costo, precioDescuento: precio.descuento,
                                                                        lineaDescuento: it.linea.descuento, utilidad: precio.utilidad,
                                                                        clienteDescuento: clienteDescuento, impuestos: it.impuestos,
                                                                        grupoDescuento: it.grupo.descuento])

                    filaMod.id_articulo       = it.id
                    filaMod.codigo            = it.codigo
                    filaMod.descripcion       = it.descripcion
                    filaMod.unidad            = it.unidad
                    filaMod.impuestos         = it.impuestos
                    filaMod.id_linea          = it.linea.id
                    filaMod.linea             = it.linea.descripcion
                    filaMod.costo             = precio.costo
                    filaMod.utilidad          = precio.utilidad
                    filaMod.precioDescuento   = precio.descuento
                    filaMod.id_grupo          = it.grupo.id
                    filaMod.grupo             = it.grupo.descripcion
                    filaMod.precio            = precioFinal.total
                    filaMod.existencias       = existencias.cantidad

                    filaMod.save()

                    //Elimino todos los códigos para éste artículo en cachécodigos
                    RAMCacheCodigos.executeUpdate("delete from nadesicoi.RAMCacheCodigos where id_articulo = ?", [it.id])
                    //Agrego el código principal
                    filaMod = new RAMCacheCodigos(id_articulo:it.id, codigo:it.codigo)
                    filaMod.save()                    
                    //Agrego los alternos
                    def cods  = it.codigos.toArray()
                    for(int i = 0; cods.size()>0 && cods.size()>i; i++) {
                        renglon = new RAMCacheCodigos(id_articulo: it.id, codigo:cods[i].codigo)
                        renglon.save()
                    }
                    /*
                    def codsAlt = RAMCacheCodigos.findById_articulo(it.id)
                    if(codsAlt == null) {
                        filaMod = new RAMCacheCodigos(id_articulo:it.id, codigo:it.codigo)
                        filaMod.save()
                    } else {
                        RAMCacheCodigos.executeUpdate("UPDATE nadesicoi.RAMCacheCodigos as rcc SET codigo = ? WHERE "+
                                                      "id_articulo = ? AND nCodigo = 1", [it.codigo, it.id])
                    }
                    */
                 }
                 return 0
        }
    }
}

